package com.applet.system.controller.comon;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import com.applet.system.entity.HttpResult;
import com.applet.system.entity.UserContext;
import com.applet.system.utils.FileUtils;
import com.applet.system.utils.RequestUtils;
import com.applet.system.utils.StringUtils;
import com.applet.system.utils.UserContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;

import com.applet.system.entity.LoginLog;
import com.applet.system.entity.User;
import com.applet.system.entity.dto.UserDto;
import com.applet.system.service.ActionService;
import com.applet.system.service.LoginLogService;
import com.applet.system.service.MenuService;
import com.applet.system.service.UserService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/system")
public class IndexController {
	
	public static final String VERIFICATION_CODE_KEY = "CONSOLE-VERIFICATION-CODE";
	
	@Autowired
	private UserService userServiceImpl;
	
	@Autowired
	private MenuService menuServiceImpl;
	
	@Autowired
	private LoginLogService loginLogServiceImpl;

	@Autowired
	private ActionService actionServiceImpl;
	
	private static final char[] chars =  "ABCDEFGHIJKLMNPQRSTUVWXYZ0123456798".toCharArray();
	
	@Value("${console.file.upload.dir}")
	private String uploadDir;

	@Value("${console.file.imgPath}")
	private String imgPath;
	
	@PostMapping("/upload")
	public HttpResult upload(HttpServletRequest request, MultipartFile file) {
		String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).toLowerCase();
        String fileName = StringUtils.getUUID();
		String FullName = new StringBuilder(fileName).append(suffix).toString();
        try {
			FileUtils.uploadFile(file.getBytes(), uploadDir, FullName);
		} catch (IOException e) {
			log.error("upload", e);
			return HttpResult.SYSTEM_ERROR;
		}
		return new HttpResult(imgPath.replace("{fileName}", fileName).replace("{suffix}", suffix.substring(1)));
	}
	
	@GetMapping("/img/{suffix}/{fileName}")
    public void img(@PathVariable("fileName")String fileName,@PathVariable("suffix")String suffix, HttpServletResponse response){
		String fullName = new StringBuilder(uploadDir).append(File.separator).append(fileName).append(".").append(suffix).toString();
    	File file=new File(fullName);
    	if (file.exists()) {
        	InputStream is;
    		try {
    			is = new FileInputStream(file);
    	    	BufferedImage bi=ImageIO.read(is);
    	    	response.setContentType("image/"+suffix);
    	        OutputStream os = response.getOutputStream();
    	        ImageIO.write(bi, suffix, os);
    	        is.close();
    	        os.close();
    		} catch (Exception e) {
    			log.error("/rebate/qrcode/{oi}.htm",e);
    		}
		}
    }
	
	@GetMapping(value = "/verificationCode")
    public void verificationCode(HttpServletRequest request, HttpServletResponse response) {
        // 创建一个宽100,高50,且不带透明色的image对象 100 50
        BufferedImage bi = new BufferedImage(100, 50, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        // RGB色彩
        Color c = new Color(214, 214, 214);
        // 框中的背景色
        g.setColor(c);
        // 颜色填充像素
        g.fillRect(0, 0, 100, 50);
        // 定义验证码字符数组
        Random r = new Random();
        int index;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            index = r.nextInt(chars.length);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            Font font = new Font("Arial", Font.BOLD, 22+r.nextInt(5));
            g.setFont(font);
            g.drawString(String.valueOf(chars[index]), (i * 18) + 10, 30);
            sb.append(chars[index]);
        }
        g.drawLine(r.nextInt(5), 10+r.nextInt(30), 90+r.nextInt(10), 20+r.nextInt(20));
        request.getSession().setAttribute(VERIFICATION_CODE_KEY, sb.toString());
        try {
            ImageIO.write(bi, "png", response.getOutputStream());
        } catch (IOException e) {
            log.error("verificationCode", e);
        }
    }
	
    @PostMapping(value="/login")
    public HttpResult login(HttpServletRequest request, User user, String capText) {
    	if (StringUtils.isEmpty(capText) || StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())) {
    		return HttpResult.PARAM_ERROR;
		}
    	HttpSession session = request.getSession();
    	Object cap = session.getAttribute(VERIFICATION_CODE_KEY);
    	if (cap == null  || !capText.equalsIgnoreCase(cap.toString())) {
    		StringBuilder sb = new StringBuilder();
            Random r = new Random();
	        for (int i = 0; i < 4; i++) {
	            sb.append(chars[r.nextInt(chars.length)]);
	        }
    		request.getSession().setAttribute(VERIFICATION_CODE_KEY, sb.toString());
			return HttpResult.fail("验证码输入有误");
		}
    	User u = this.userServiceImpl.getUserByPassword(user);
    	if (u == null) {
    		return HttpResult.fail("账号不存在，或密码输入有误");
		}
    	if (!u.getIsEnable()) {
    		return HttpResult.fail("您的账号已被禁用");
		}
    	// 登录记录
    	this.loginLogServiceImpl.addLoginLog(new LoginLog(user.getUserName(), RequestUtils.getIpAddress(request)));
    	// 记录到SESSION
    	session.setAttribute(UserContext.class.getName(), JSON.toJSONString(new UserContext(u.getId(),u.getNickName(),u.getUserName(),u.getHeadImg(),u.getPhone())));
        // 加载用户动作权限到redis中
		Object  abc=request.getSession().getAttribute(UserContext.class.getName());
    	this.actionServiceImpl.loadActionAuth(u.getId());
    	return new HttpResult(u);
    }

    /**
     * 当前登录用户的菜单权限
     * @return
     */
    @GetMapping(value="/resource")
    public HttpResult resource(HttpServletRequest request){
    	return new HttpResult(this.menuServiceImpl.getMenusAuth(UserContextUtil.get().getId()));
    }
	@GetMapping(value="/resourceV2")
	public HttpResult resource2(@Qualifier Long userId){
		//request.getSession().getAttribute(UserContext.class.getName());
		return new HttpResult(this.menuServiceImpl.getMenusAuth(userId));
	}
    
    /**
     * 获取当前登录用户信息
     * @return
     */
    @GetMapping(value="/userInformation")
    public HttpResult userInformation(){
    	return new HttpResult(UserContextUtil.get());
    }

    /**
     * 获取当前登录用户信息
     * @return
     */
    @GetMapping(value="/signOut")
    public HttpResult signOut(HttpServletRequest request){
    	request.getSession().removeAttribute(UserContext.class.getName());
		UserContextUtil.set(null);
    	return new HttpResult(UserContextUtil.get());
    }
    
    /**
     * 修改个人信息
     */
    @PostMapping(value="/updateSelfInformation")
    public HttpResult updateSelfInformation(HttpServletRequest request,User user) {
    	UserContext uc = UserContextUtil.get();
    	user.setId(uc.getId());
    	user.setEditor(uc.getUserName());
    	this.userServiceImpl.updateSelfInformation(user);
    	// 更新缓存数据
    	request.getSession().setAttribute(UserContext.class.getName(), JSON.toJSONString(new UserContext(uc.getId(),user.getNickName(),uc.getUserName(),user.getHeadImg(),user.getPhone())));
    	return HttpResult.OK;
    }
    

    /**
     * 修改个人密码
     */
    @PostMapping(value="/updateSelfPassword")
    public HttpResult updateSelfPassword(UserDto user) {
    	UserContext uc = UserContextUtil.get();
    	user.setId(uc.getId());
    	user.setUserName(uc.getUserName());
    	user.setEditor(uc.getUserName());
    	if (this.userServiceImpl.updateSelfPassword(user) == 0) {
			return HttpResult.fail("原密码输入有误");
		}
    	return HttpResult.OK;
    }
    
    /**
     * 校验动作权限
     */
    @PostMapping(value="/validateActionAuth")
    public HttpResult validateActionAuth(@RequestParam("codes[]") List<String> codes) {
    	return new HttpResult(this.actionServiceImpl.validateCodes(UserContextUtil.get().getId(), codes));
    }
    @PostMapping(value="/validateActionAuthV2")
    public HttpResult validateActionAuthV2(@RequestParam("codes[]") List<String> codes,@Qualifier  Long userId) {
        return new HttpResult(this.actionServiceImpl.validateCodes(userId, codes));
    }
}
